package gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Date;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.Database;
import model.Pallet;

/**
 * The panel where the user can search for Pallets.
 */

public class SearchPanel extends JPanel implements ActionListener{

	
	private JTextField from;
	private JTextField to;
	private JComboBox cookieNames;
	private Date f;
	private Date t;
	private JButton search;
	private MessageLabel message;
	private JList pallets;
	private InformationPanel info;
	private Database db;
	private JPanel main;
	private BigBlock block;
	
	private static final String ALL = "All";
	
	/**
	 * The constructor which constructs the visual search panel.
	 * @param db is the database access class.
	 */
	public SearchPanel(Database db){
		this.db = db;
		setLayout(new BorderLayout());
		JPanel north = new JPanel(new GridLayout(2,1));
		JPanel searchField = new JPanel(new GridLayout(1,6));
		searchField.add(search=new JButton("Search"));
		search.addActionListener(this);
		searchField.add(new JLabel("From",JLabel.CENTER));
		searchField.add(from=new JTextField(Database.getDate(1970, 1, 1)));
		searchField.add(new JLabel("To",JLabel.CENTER));
		searchField.add(to=new JTextField(Database.getDate(2100, 1, 1)));
		searchField.add(cookieNames=new JComboBox(db.getCookieNames()));
		cookieNames.addItem(ALL);
		north.add(searchField);
		north.add(message=new MessageLabel("Search for all pallets produced between the dates from and to!"));
		add(north, BorderLayout.NORTH);
		main = new JPanel(new GridLayout(1,2));
		add(main, BorderLayout.CENTER);
		main.add(new JScrollPane(pallets=new JList()));
		pallets.addListSelectionListener(new ListSelectionListener(){
			/** 
			 * valueChanged is fired when a Pallet is selected from the List. Updates the information panel.
			 * @param e is the SelectionEvent which was fired.
			 */
			public void valueChanged(ListSelectionEvent e) {
				Pallet pallet = (Pallet)pallets.getSelectedValue();
				if(pallet!=null){
					info.setInformation(pallet);
				}
			}
		});
		main.add(info = new InformationPanel());
	}

	/**
	 * What happens when the player click on the Search button. Sets user message and start search if there's no error.
	 * @param event 
	 */
	public void actionPerformed(ActionEvent event) {
		try{
			f = Date.valueOf(from.getText());
		}catch(Exception e){
			message.setMessage("The From date needs to follow the date format: YYYY-MM-DD",true);
			return;
		}
		try{
			t = Date.valueOf(to.getText());
		}catch(Exception e){
			message.setMessage("The To date needs to follow the date format: YYYY-MM-DD",true);
			return;
		}
		String c = null;
		if(cookieNames.getSelectedItem()==null){
			message.setMessage("A cookie need to be selected!",true);
			return;
		}else{
			c = cookieNames.getSelectedItem().toString();
			if(c.equals(ALL)){
				c = null;
			}
		}
		updateSearch(c);
		message.setMessage("Search is completed!",false);
	}
	
	/**
	 * updateSearch makes a new search and updates the panel with said search.
	 * @param c is the cookieName to be searched for.
	 */
	public void updateSearch(String c){
		ArrayList<Pallet> pps = db.searchPallets(f, t, c);
		if(pps==null){
			message.setMessage("An database error occured!",true);
			return;
		}
		if(block!=null){
			remove(block);
		}
		main.remove(info);
		main.add(info = new InformationPanel());
		pallets.setListData(pps.toArray(new Pallet[0]));
		add(block = new BigBlock(c, f, t), BorderLayout.SOUTH);
		updateUI();
	}
	
	/**
	 * BigBlock extends JButton and Blocks all Pallets which is located in the list.
	 */
	private class BigBlock extends JButton implements ActionListener{
		private String cookieName;
		private Date f;
		private Date t;
		
		/**
		 * Constructor of BigBlock.
		 * @param cookieName is the cookieName of the cookie to be blocked.
		 * @param f is the date from where to block.
		 * @param t is the date to where to block.
		 */
		public BigBlock(String cookieName, Date f, Date t){
			this.cookieName = (cookieName==null?ALL:cookieName);
			this.f = f;
			this.t = t;
			Dimension d = new Dimension(50,50);
			setText("Block all in list");
			setFont(new Font("Arial",Font.BOLD,28));
			setSize(d);
			setPreferredSize(d);
			addActionListener(this);
		}

		/**
		 * the event which creates the block and updates the search panel.
		 * @param event is the event which was fired.
		 */
		public void actionPerformed(ActionEvent event) {
			if(!cookieName.equals(ALL)){
				block(cookieName);
				updateSearch(cookieName);
			}else{
				for(int i = 0;i<cookieNames.getItemCount();i++){
					if(!block(cookieNames.getItemAt(i).toString())){
						return;
					}
				}
				updateSearch(null);
			}
		}
		/**
		 * Makes the database block pallets, sets user message if success or failed.
		 * @param cookieName is the cookie which is to be blocked.
		 * @return true if blocked, else false.
		 */
		private boolean block(String cookieName){
			if(!db.blockPallets(f, t, cookieName)){
				message.setMessage("Database error occured!", true);
				return false;
			}else{
				message.setMessage("All pallets of "+cookieName+" produced from "+f.toString()+" to "+t.toString()+" is blocked!", false);
				return true;
			}
		}
	}
}
